package com.pie4cloud.pie.dmz.client;


import com.alibaba.fastjson.JSON;
import com.pie4cloud.pie.common.core.util.RedisUtil;
import com.pie4cloud.pie.job.api.entity.DmzEntity;
import com.pie4cloud.pie.job.executor.utils.netty.NettyClient;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class NettyConnManage {


	@Autowired
	private NettyClient nettyClient;
	@Autowired
	private RedisUtil redisUtil;
	private static String monitorDetail = "MONITOR_DETAIL";

	Logger logger = LoggerFactory.getLogger(this.getClass());
	//private AtomicInteger roundRobin = new AtomicInteger(0);
	//private CopyOnWriteArrayList<Channel> channels = new CopyOnWriteArrayList<>();
	private Map<SocketAddress, Channel> channelNodes = new ConcurrentHashMap<>();
	public  Channel chooseChannel() {
		DmzEntity dmzEntity=this.getServiceInfo();
		if(null!=dmzEntity){
			SocketAddress remotePeer = new InetSocketAddress(dmzEntity.getHost(), dmzEntity.getNettyPort());
			if(null!=channelNodes.get(remotePeer)){
				Channel channel=channelNodes.get(remotePeer);
				if(channel.isOpen()){
					return channel;
				}
			}
			channelNodes.remove(remotePeer);
			this.connectServerNode(remotePeer);
			return channelNodes.get(remotePeer);
		}else {
			return null;
		}

	}


	public DmzEntity getServiceInfo() {
		List<DmzEntity> dmzEntities=new ArrayList<>();
		Map<Object, Object> map = redisUtil.hmget(monitorDetail);
		for (Object o:map.values()) {
			String str= (String) o;
			DmzEntity dmzEntity= JSON.parseObject(str,DmzEntity.class);
			if(dmzEntity.getSystemInfoDto().getIsUsable()==0){
				dmzEntities.add(dmzEntity);
			}
		}
		int size = dmzEntities.size();
		Random random = new Random();
		DmzEntity dmzEntity = dmzEntities.get(random.nextInt(size));
		return dmzEntity;
	}


	private synchronized void connectServerNode(SocketAddress address){
		try {
			if(null!=channelNodes.get(address)){
				return;
			}
			Channel channel = nettyClient.doConnect(address);
			addChannel(channel,address);
		} catch (InterruptedException e) {
			e.printStackTrace();
			logger.info("未能成功连接到服务器:{}",address);
		}
	}
	private void addChannel(Channel channel,SocketAddress address) {
		logger.info("加入Channel到连接管理器.{}",address);
		//channels.add(channel);
		channelNodes.put(address, channel);
	}

	public void removeChannel(Channel channel){
		logger.info("从连接管理器中移除失效Channel.{}",channel.remoteAddress());
		SocketAddress remotePeer = channel.remoteAddress();
		channelNodes.remove(remotePeer);
	}
}
